package com.xinsoft.config;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.xinsoft.constant.Const;
import com.xinsoft.utils.SysUser;
import com.xinsoft.utils.TokenUtil;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.xinsoft.constant.Const.DEL_FLAG_NORMAL;
import static com.xinsoft.constant.Const.Field.*;

/**
 * 公共字段填充
 * <p>
 * 当前填充规则：
 * 1. 新增时，自动填充 创建人/时间，修改人/时间，区划编码（包含拆分字段，管区字段除外），删除标识
 * 2. 修改时，自动填充 修改人/时间
 * <p>
 * 注：
 * 1. 由于依赖的framework中已经有了cn.o.framework.common.handler.FieldMetaObjectHandler
 * 因此必须在启动类中排除框架中的FieldMetaObjectHandler注入
 * 2. MetaObjectHandler提供的默认方法的策略均为:如果属性有值则不覆盖,如果填充值为null则不填充
 * <p>
 * 参考：https://mp.baomidou.com/guide/auto-fill-metainfo.html
 *
 * @author Li9527
 * @date 2021/02/23 17:25
 */
@Component
public class FieldMetaObjectHandler implements MetaObjectHandler {

    /**
     * 排除自动填充的实体
     */
    public static List<String> excludeClasses = new ArrayList<String>();

    static {
        //系统操作日志
        excludeClasses.add("com.szyunke.common.web.log.entity.OperaLog");
        //系统登陆日志
        excludeClasses.add("com.szyunke.common.web.log.entity.LoginLog");
    }

    @Override
    public void insertFill(MetaObject metaObject) {
        // 解析token, 得到用户id
        SysUser sysUser = TokenUtil.getUser();
        if(sysUser != null){
            sysUser.setId(sysUser.getId());
            // 填充创建人、创建时间
            this.insertField(metaObject, sysUser, CREATE_USER_ID, CREATE_TIME,UPDATE_USER_ID,UPDATE_TIME,DEL_FLAG);
        }else{
            // 填充创建人、创建时间
            SysUser sysUser1 = new SysUser();
            sysUser1.setId(Const.ADMIN_UID);
            this.insertField(metaObject, sysUser1, CREATE_USER_ID, CREATE_TIME,UPDATE_USER_ID,UPDATE_TIME,DEL_FLAG);
        }

        // 填充更新人、更新时间 - 视项目需要放开
//        this.updateField(metaObject, sysUser, UPDATE_USER_ID, UPDATE_TIME);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        // 解析token, 得到用户id
        SysUser sysUser = TokenUtil.getUser();
        if(sysUser != null){
            sysUser.setId(sysUser.getId());
            this.updateField(metaObject, sysUser, UPDATE_USER_ID, UPDATE_TIME);
        }else{
            SysUser sysUser1 = new SysUser();
            sysUser1.setId(Const.ADMIN_UID);
            this.updateField(metaObject, sysUser1, UPDATE_USER_ID, UPDATE_TIME);
        }

    }

    /**
     * 更新属性
     *
     * @param metaObject  元数据
     * @param currentUser 当前用户
     * @param userId      人创建/更新标识
     * @param time        时间创建/更新标识
     */
    public void insertField(MetaObject metaObject, SysUser currentUser, String userId, String time, String updateUserId,String updateTime,String delFlag) {
        if (metaObject.hasSetter(userId)) {
            if (Integer.class.getName().equals(metaObject.getGetterType(userId).getName())) {
                setFieldValByName(userId, currentUser.getId(), metaObject);
            } else {
                setFieldValByName(userId, String.valueOf(currentUser.getId()), metaObject);
            }
        }
        if (metaObject.hasSetter(time) && getFieldValByName(time, metaObject) == null) {
            if (LocalDateTime.class.getName().equals(metaObject.getGetterType(time).getName())) {
                setFieldValByName(time, DateUtil.now(), metaObject);
            } else {
                setFieldValByName(time, new Date(), metaObject);
            }
        }
        if (metaObject.hasSetter(updateUserId)) {
            if (Integer.class.getName().equals(metaObject.getGetterType(updateUserId).getName())) {
                setFieldValByName(updateUserId, currentUser.getId(), metaObject);
            } else {
                setFieldValByName(updateUserId, String.valueOf(currentUser.getId()), metaObject);
            }
        }
        if (metaObject.hasSetter(updateTime) && getFieldValByName(updateTime, metaObject) == null) {
            if (LocalDateTime.class.getName().equals(metaObject.getGetterType(updateTime).getName())) {
                setFieldValByName(updateTime, DateUtil.now(), metaObject);
            } else {
                setFieldValByName(updateTime, new Date(), metaObject);
            }
        }
        if (metaObject.hasSetter(delFlag)) {
            if (Integer.class.getName().equals(metaObject.getGetterType(delFlag).getName())) {
                setFieldValByName(delFlag, DEL_FLAG_NORMAL, metaObject);
            }
        }
    }

    /**
     * 更新属性
     *
     * @param metaObject  元数据
     * @param currentUser 当前用户
     * @param userId      人创建/更新标识
     * @param time        时间创建/更新标识
     */
    public void updateField(MetaObject metaObject, SysUser currentUser, String userId, String time) {
        if (metaObject.hasSetter(userId)) {
            if (Integer.class.getName().equals(metaObject.getGetterType(userId).getName())) {
                setFieldValByName(userId, currentUser.getId(), metaObject);
            } else {
                setFieldValByName(userId, String.valueOf(currentUser.getId()), metaObject);
            }
        }
        if (metaObject.hasSetter(time) && getFieldValByName(time, metaObject) == null) {
            if (LocalDateTime.class.getName().equals(metaObject.getGetterType(time).getName())) {
                setFieldValByName(time, DateUtil.now(), metaObject);
            } else {
                setFieldValByName(time, new Date(), metaObject);
            }
        }
    }
}
